<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.global.js"></script>
</head>
<body>
    <div id="app">
        <h3>{{msg}}</h3>
        <p ref="p">{{count}}</p>
        <p >{{count}}---{{doubleCount}}</p>
        <p><button @click="addCount">点击count++</button></p>
        <hr>
       <p>{{name.firstName}}-----{{name.lastName}}</p>
        <button @click="changeName">changeName</button>

    </div>
</body>

<!-- <script>
    // Vue3  => 选项式API

    console.log(Vue);

    var {createApp} = Vue;


    // createApp创建实例(应用)的方法 => 可以接收options选项配置 => 返回创建实例(应用)

    // 声明式渲染
    var app = createApp({
        data(){
            return {
                msg:"hello world",
                count:1,
            }
        },
        methods:{
            addCount(){
                this.count++;
            }
        },
        computed:{
            doubleCount(){
                return this.count * 2
            },
            tripleCount(){
                return this.count * 3
            }
        },
        watch:{
            count(newVal,oldVal){
                console.log("count改变了",newVal,oldVal);
            }
        },
        mounted(){
            // this ->代理对象(需要通过代理对象来访问数据/方法)
            console.log(this);
        }
    })

    console.log(app);
    app.mount("#app");



</script> -->

<script>
    console.dir(Vue);  // 打印一个对象的属性和方法 
    var {createApp} = Vue;

   

    var app = createApp({
        // data(){},

        // 选项式写法  -> this指向 Proxy对象(依赖于代理对象进行取值和赋值)
        // computed:{},
        // methods: {},
        // watch:{}

        // 组合式  -> 原理(闭包)
        setup(props) {  // props组件通信时用于接收数据的方法之一

            let {ref,reactive,readonly,computed,watch,watchEffect,nextTick} = Vue;
            let {isRef,isReactive,isReadonly,isProxy,unref,toRef,toRefs} = Vue;
            let {shallowRef,triggerRef} = Vue;

            let msg = ref("hello world");  
            // console.log(msg);
      

            let count = ref(0);
            // console.log(count);

            // reactive  一般用于引用类型 返回一个对象的响应式代理(proxy对象)
            let info = reactive({
                user:"a123123",
                pwd:"123123",
            })
            info.height = "175cm";
        

            let obj = readonly({
                user:"a123123",
                pwd:"123123",
            })


            // 方法  
            let addCount = ()=>{
                count.value++
            }

            // 计算属性   接受一个 getter 函数，返回一个只读的响应式 ref 对象。该 ref 通过 .value 暴露 getter 函数的返回值。它也可以接受一个带有 get 和 set 函数的对象来创建一个可写的 ref 对象。
            // let doubleCount = computed(()=>{  //默认只有取值
            //     return count.value * 2;
            // })

            let doubleCount = computed({
                get(){
                    return count.value * 2;
                },
                set(val){
                    count.value = val / 2;
                }
            })


            // console.log("msg",isRef(msg));
            // console.log("doubleCount",isRef(doubleCount));
            // console.log("info",isReactive(info));
            // console.log("obj",isReadonly(obj));
            // console.log("info",isProxy(info));

            // 如果参数是 ref，则返回内部值，否则返回参数本身
            // var a = ref(100)
            // console.log(unref(a));  // a.value


            // 基于响应式对象上的一个属性，创建一个对应的 ref。这样创建的 ref 与其源属性保持同步：改变源属性的值将更新 ref 的值，反之亦然。

            // var name = reactive({
            //     firstName:"Tom",
            //     lastName:"Zhang",
            // })

            // var firstName = toRef(name,"firstName");
            // console.log(firstName);


            // firstName.value = "Jone";
            // console.log(name.firstName);
            // name.firstName = "Mike";
            // console.log( firstName.value);

            // shallowRef   ref() 的浅层作用形式。 只监听数据.value的值发生改变 (如果数据是引用类型,引用类型的属性发生改变 -> 无法监听到)
            var name = shallowRef({
                firstName:"Tom",
                lastName:"Zhang",
            })
            // console.log(name.value);  // 只监听数据.value的值发生改变 
            
            
            watchEffect(()=>{
                console.log("name发生改变", name.value.firstName,name.value.lastName);
            })
            
            let  changeName = () => {
                console.log(1111111);
                name.value.firstName = "Jack";
                console.log(name.value);

                triggerRef(name);   // 强制触发依赖于一个浅层 ref 的副作用，这通常在对浅引用的内部值进行深度变更后使用
            }





           

            return {
                msg,
                count,
                info,
                addCount,
                doubleCount,
                name,
                changeName,
            }
            
        }



    });


    app.mount("#app");



</script>

</html>